package com.sena.engine.snmp.api;

import com.sena.engine.common.exception.SenaSnmpRunTimeException;
import com.sena.engine.snmp.base.SnmpCommunication;
import com.sena.engine.snmp.base.SnmpTarget;
import com.sena.engine.snmp.config.DefaultConstant;
import com.sena.engine.snmp.handler.RefreshHandler;
import com.sena.engine.snmp.handler.SelectHandler;
import com.sena.engine.snmp.handler.SetHandler;
import com.sena.engine.snmp.handler.UpdateHandler;
import com.sena.engine.snmp.utils.SnmpUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.smi.Variable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Admin
 */
public class SenaSnmpApiImp implements SenaSnmpApi {


    private static final Logger log = LoggerFactory.getLogger(SenaSnmpApiImp.class);

    @Override
    public boolean checkSnmpAgentActive(SnmpTarget snmpTarget) {
        Snmp snmp = null;
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            String str = new SelectHandler().getValue("1.3.6.1.2.1.1.1.0", snmp, target).toString();
            return StringUtils.isNotBlank(str);
        } catch (Exception exception) {
            return false;
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    /**
     * @param oid
     * @param nodeOid
     * @param value
     * @param snmpTarget
     * @throws SenaSnmpRunTimeException
     */
    @Override
    public void setOIDValue(String oid, String nodeOid, String value, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException {
        Snmp snmp = null;
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            new SetHandler().setValue(oid, nodeOid, value, snmp, target);
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    @Override
    public String getOIDValue(String oid, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException {
        Snmp snmp = null;
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable variable = new SelectHandler().getValue(oid, snmp, target);
            if (variable == null) {
                return null;
            } else {
                return variable.toString();
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    @Override
    public Long getOIDLongValue(String oid, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException {
        Snmp snmp = null;
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable variable = new SelectHandler().getValue(oid, snmp, target);
            if (variable == null) {
                return null;
            } else {
                return variable.toLong();
            }
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    /**
     * @param oid
     * @param snmpTarget
     * @return
     * @throws SenaSnmpRunTimeException
     */
    @Override
    public String getNextOIDValue(String oid, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException {
        Snmp snmp = null;
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable value = new SelectHandler().getNextValue(oid, snmp, target);
            return value == null ? null : value.toString();
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    @Override
    public Object getMibObject(Object obj, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException, IOException {
        Snmp snmp = null;
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            new RefreshHandler().reFresh(obj, snmp, target);
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
        return obj;
    }

    @Override
    public void update(Object obj, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException {
        Snmp snmp = null;
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            new UpdateHandler().update(obj, snmp, target);
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    @Override
    public List getAllTableData(Class clazz, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException {
        Snmp snmp = null;
        List retList = new ArrayList();
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            retList = new  SelectHandler().getAllTableData(snmp, target, clazz);
            return retList;
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    @Override
    public List<List<String>> getAllOIDTableData(SnmpTarget snmpTarget, List<String> oids) throws SenaSnmpRunTimeException, IOException {
        Snmp snmp = SnmpCommunication.createSnmp(snmpTarget);
        List<List<String>> resList = new ArrayList<>();
        try {
            Target Target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            List list =new SelectHandler().getAllOIDTableData(snmp, Target, oids);
            resList = list;
            return resList;
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    @Override
    public void addTableRow(Object object, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException, IOException {
        Snmp snmp = SnmpCommunication.createSnmp(snmpTarget);
        try {
            Target Target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            new UpdateHandler().update(object, snmp, Target);
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }

    @Override
    public void delTableRow(Object object, SnmpTarget snmpTarget) throws SenaSnmpRunTimeException {
        Snmp snmp = null;
        try {
            snmp = SnmpCommunication.createSnmp(snmpTarget);
            Target Target = SnmpCommunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            new UpdateHandler().update(object, snmp, Target);
        } catch (Exception e) {
            throw new SenaSnmpRunTimeException(e.getMessage());
        } finally {
            SnmpUtils.closeSnmp(snmp);
        }
    }
}
